package cn.oi.klittle.era.base

import android.app.Activity
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.Bitmap
import android.graphics.Color
import android.os.Build
import android.os.Bundle
import android.view.*
import androidx.fragment.app.Fragment
import cn.oi.klittle.era.activity.photo.config.PictureConfig
import cn.oi.klittle.era.activity.photo.entity.KLocalMedia
import cn.oi.klittle.era.activity.photo.manager.KPictureSelector
import cn.oi.klittle.era.comm.KToast
import cn.oi.klittle.era.exception.KCatchException
import cn.oi.klittle.era.helper.KUiHelper
import cn.oi.klittle.era.utils.KAssetsUtils
import cn.oi.klittle.era.utils.KLoggerUtils
import cn.oi.klittle.era.utils.KPermissionUtils
import cn.oi.klittle.era.utils.KPictureUtils
import java.io.File
//import org.jetbrains.anko.act
//import org.jetbrains.anko.support.v4.act//不要引用这个，防止androdx冲突
import java.lang.Exception

/**
 * 继承本Fragment，主构造函数传入一个布局id或者一个View即可(一般都是frameLayout控件)。然后就可以像Activity一样使用了。
 * Activity中加载说明：supportFragmentManager.beginTransaction().replace(px.id("frameLayoutID"),Myfragment()).commit()即可;已经集成到KBaseActivity里面去了。replace()方法。
 * Fragment中最好使用：childFragmentManager.beginTransaction()；fixme 也已经集成到KBaseFragment里面去了，replace()方法。 Fragment里面还包含Fragment。
 * fixme 生命周期：调用replace（）之后，新的Fragment:onCreateView(),onResume();旧的Fragment:onDestroy()。每次切换都会重新执行。
 * fixme showFragment()第一次显示的时候会执行生命周期。其后再显示就不会在执行生命周期了。建议使用show()。
 * Created by 彭治铭 on 2018/4/20.
 */
abstract open class KBaseFragment(var layout: Int = 0, var content: View? = null) : Fragment() {

    var act = activity

    //触摸点击效果。isRipple是否具备波浪效果
    open fun onPress(view: View?, isRipple: Boolean = true) {
        KBaseView.onPress(view, isRipple)
    }

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        if (act == null) {
            act = activity
        }
        if (layout <= 0) {
            content?.let {
                return it
            }
            content = onCreateView()//子类可以直接重写onCreateView来创建View
            content?.let {
                return it
            }
            return super.onCreateView(inflater, container, savedInstanceState)
        } else {
            //获取xml布局
            if (content == null) {
                content = inflater.inflate(layout, container, false)
            }
            return content
        }
    }

    //fixme 如果传入的布局和view都为空。则可重写以下方法,一般都是重写的该方法。
    open fun onCreateView(): View? {
        //return UI { }.view//使用Anko布局
        return null
    }


    //通过ID获取控件
    fun <T> findViewById(id: Int): T? {
        try {
            var view = content?.findViewById<View>(id)
            return view as? T
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return null
    }

    override fun onResume() {
        super.onResume()
        setStatusBarDrak(isDark())
    }

    var isCurrentDark = KBaseApplication.getInstance().isDeaultDark//fixme 记录当前状态栏字体的颜色

    //true 状态栏字体颜色为 黑色，false 状态栏字体颜色为白色。子类可以重写
    protected open fun isDark(): Boolean {
        return isCurrentDark
    }

    //设置状态栏字体颜色,true黑色（深色），false白色（浅色）
    open fun setStatusBarDrak(isDark: Boolean) {
        activity?.window?.let {
            isCurrentDark = isDark//记录当前状态栏字体的颜色
            KBaseApplication.getInstance().setStatusBarDrak(it, isCurrentDark)
        }
    }

    open fun setNavigationBarColor(color: Int) {
        //对版本号21 即5.0及以上才有效。
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            activity?.getWindow()?.setNavigationBarColor(color);
        }
    }

    open fun setNavigationBarColor(color: String) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            activity?.getWindow()?.setNavigationBarColor(Color.parseColor(color));
        }
    }

    /**
     * 界面和底部导航栏融为一体,親測有效。
     */
    open fun setNavigationBarTransparent() {
        // 透明导航栏，屏幕的底部[部分手机完全透明，部分手机可能半透明。]
        activity?.getWindow()?.addFlags(
                WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION)
    }

    // 两次点击按钮之间的点击间隔不能少于1000毫秒（即1秒）
    var MIN_CLICK_DELAY_TIME = 1000
    var lastClickTime: Long = System.currentTimeMillis()//记录最后一次点击时间

    //判断是否快速点击，true是快速点击，false不是
    open fun isFastClick(): Boolean {
        var flag = false
        var curClickTime = System.currentTimeMillis()
        if ((curClickTime - lastClickTime) <= MIN_CLICK_DELAY_TIME) {
            flag = true//快速点击
        }
        lastClickTime = curClickTime
        return flag
    }

    //fixme 自定义点击事件，可以添加多个点击事情。互不影响
    open fun onClick(view: View?, onClick: () -> Unit) {
        //点击事件
        view?.setOnClickListener {
            //fixme 防止快速点击
            if (!isFastClick()) {
                onClick()//点击事件
            }
        }
    }

    /**
     * 在Activity应用<meta-data>元素。
     */
    open fun getMetaDataFromActivity(key: String): String? {
        if (activity == null) {
            return null
        }
        val info = activity!!.packageManager
                .getActivityInfo(activity!!.componentName,
                        PackageManager.GET_META_DATA)
        val msg = info?.metaData?.getString(key)
        return msg
    }

    /**
     * 在application应用<meta-data>元素。
     */
    open fun getMetaDataFromApplication(key: String): String? {
        if (activity == null) {
            return null
        }
        val appInfo = activity!!.packageManager
                .getApplicationInfo(activity!!.packageName,
                        PackageManager.GET_META_DATA)

        return appInfo.metaData.getString(key)
    }

    open fun getColor(id: Int): Int {
        return getResources().getColor(id)
    }

    /**
     * 获取颜色值
     */
    open fun getColorFromResources(id: Int): Int {
        return getResources().getColor(id)
    }

    //默认就从Res目录下读取
    open fun getString(id: Int, formatArgs: String? = null): String {
        return getStringFromResources(id, formatArgs)
    }

    /**
     * 获取String文件里的字符,<string name="names">你好%s</string>//%s 是占位符,位置随意
     * @param formatArgs 是占位符
     */
    open fun getStringFromResources(id: Int, formatArgs: String? = null): String {
        if (formatArgs != null) {
            return this.resources.getString(id, formatArgs) as String
        }
        return this.resources.getString(id) as String
    }

    /**
     * 获取String文件里的字符串數組
     */
    open fun getStringArrayFromResources(id: Int): Array<String> {
        return resources.getStringArray(id)
    }

    open fun getBundle(): Bundle? {
        if (activity == null) {
            return null
        }
        activity!!.intent?.let {
            it.extras?.let {
                return it
            }
        }
        return null
    }

    open fun getStringFromBundle(key: String, defaultValue: String? = null): String? {
        var value = getBundle()?.getString(key, null)
        if (value == null && defaultValue != null) {
            value = defaultValue
        }
        return value
    }

    open fun startActivity(clazz: Class<*>) {
        KUiHelper.goActivity(clazz)
    }

    open fun startActivity(clazz: Class<*>, bundle: Bundle) {
        KUiHelper.goActivity(clazz, bundle, activity)
    }

    open fun goActivity(clazz: Class<*>) {
        KUiHelper.goActivity(clazz, activity)
    }

    open fun goActivity(clazz: Class<*>, bundle: Bundle) {
        KUiHelper.goActivity(clazz, bundle, activity)
    }

    open fun goActivity(intent: Intent) {
        KUiHelper.goActivity(intent, activity)
    }

    open fun goActivityForResult(clazz: Class<*>) {
        KUiHelper.goActivityForResult(clazz, activity)
    }

    open fun goActivityForResult(clazz: Class<*>, bundle: Bundle) {
        KUiHelper.goActivityForResult(clazz, bundle, activity)
    }

    open fun goActivityForResult(intent: Intent) {
        KUiHelper.goActivityForResult(intent, activity)
    }

//    /**
//     * fixme 切换Fragment
//     * @param id 控件id(一般都是frameLayout控件;用来装载Fragment)
//     * @param fragment 要切换的Fragment
//     */
//    open fun replace(id: Int, fragment: Fragment) {
//        childFragmentManager.beginTransaction().replace(id, fragment).commit()//即可
//    }


    var mFragments: ArrayList<Fragment?>? = ArrayList<Fragment?>()//记录所有的Fragment
    var mShowFragments: ArrayList<Fragment?>? = null//记录已经显示过的Fragment
    var mCurrentFragment: Fragment? = null//记录当前显示的Fragment
    fun getFragments(): ArrayList<Fragment?> {
        if (mFragments == null) {
            mFragments = ArrayList<Fragment?>()
        }
        return mFragments!!
    }

    /**
     * fixme 切换Fragment;会销毁移除之前的Fragment。生命周期会重新执行。
     * fixme 生命周期：调用replace（）之后，新的Fragment:onCreateView(),onResume();旧的Fragment:onDestroy()。每次切换都会重新执行。
     * @param id 控件id(一般都是frameLayout控件;用来装载Fragment)
     * @param fragment 要切换的Fragment
     */
    open fun replaceFragment(id: Int, fragment: Fragment?) {
        fragment?.let {
            if (fragment != mCurrentFragment) {
                mShowFragments?.let {
                    if (it.contains(fragment)) {
                        it.remove(fragment)
                    }
                }
                childFragmentManager.beginTransaction().replace(id, it).commit()//即可
                mCurrentFragment = it
            }
        }
    }

    //fixme 不需要add()添加，就可以直接调用replace（）
    open fun replaceFragment(view: View?, fragment: Fragment?) {
        view?.let {
            if (it.id == null || it.id < 0) {
                //id没有设置是，默认是-1.
                KLoggerUtils.e("replaceFragment()所依赖的容器对象View id为空。", isLogEnable = true)
                KToast.showError("replaceFragment()所依赖的容器对象View id为空。")
            } else {
                it.id?.let {
                    replaceFragment(it, fragment)
                }
            }
        }
    }

    //添加，显示之前，一定要先添加。fixme 里面做了防重复添加。
    open fun addFragment(id: Int, fragment: Fragment?) {
        if (fragment != null) {
            getFragments()?.let {
                if (!it.contains(fragment)) {//判断是否已存在，防止重复添加。
                    it.add(fragment)
                    childFragmentManager.beginTransaction().add(id, fragment)
                            .commit()//commit（）必须执行才有效。
                }
            }
        }
    }

    open fun addFragment(view: View?, fragment: Fragment?) {
        view?.let {
            if (it.id == null || it.id < 0) {
                //id没有设置是，默认是-1.
                KLoggerUtils.e("addFragment()所依赖的容器对象View id为空。", isLogEnable = true)
                KToast.showError("addFragment()所依赖的容器对象View id为空。")
            } else {
                it.id?.let {
                    addFragment(it, fragment)
                }
            }
        }
    }

    //移除
    open fun removeFragment(fragment: Fragment?) {
        if (fragment != null) {
            getFragments()?.let {
                if (it.contains(fragment)) {
                    it.remove(fragment)
                    childFragmentManager.beginTransaction().remove(fragment).commit()
                    mShowFragments?.let {
                        if (it.contains(fragment)) {
                            it.remove(fragment)
                        }
                    }
                }
            }
        }
    }

    //隐藏
    open fun hiddenFragment(fragment: Fragment?) {
        if (fragment != null) {
            getFragments()?.let {
                if (it.contains(fragment)) {
                    childFragmentManager.beginTransaction().hide(fragment).commit()
                }
            }
        }
    }

    /**
     * fixme 显示指定的Fragment。第一次显示时会执行生命周期。后面第二次，三次就不会再执行。下面方法里，
     * fixme 第二次（多次）显示会手动调用onResume（）
     */
    open fun showFragment(fragment: Fragment?) {
        if (fragment == null) {
            return
        }
        if (fragment == mCurrentFragment) {
            return//防止重复调用。
        }
        getFragments()?.let {
            it?.forEach {
                it?.let {
                    if (fragment != it) {
                        childFragmentManager.beginTransaction().hide(it)
                                .commit()//先隐藏其他的Fragment();commit()必须执行才有效。
                    }
                }
            }
        }
        getFragments()?.let {
            if (it.contains(fragment)) {
                childFragmentManager.beginTransaction().show(fragment).commit()//最后显示指定Fragemnt()
                mCurrentFragment = fragment
                if (mShowFragments == null) {
                    mShowFragments = ArrayList()
                }
                mShowFragments?.let {
                    if (it.contains(fragment)) {
                        fragment?.onResume()//fixme 第二次之后不会在执行生命周期。所有手动调用一次onResume()
                    } else {
                        it.add(fragment)//第一次显示，添加进去。
                    }
                }
            } else {
                KLoggerUtils.e("showFragment()要显示的Fragment对象不存在，请先添加。", isLogEnable = true)
            }
        }
    }


    //fixme 自己的图片选择器
    open fun pictrueSelectorForLocalMedia(selectionMedia: MutableList<KLocalMedia>? = KPictureSelector.selectionMedia, type: Int = PictureConfig.TYPE_IMAGE, maxSelectNum: Int = 1, imageSpanCount: Int = KPictureSelector.imageSpanCount, isCompress: Boolean = true, isCamera: Boolean = true, selectCallback: ((selectDatas: MutableList<KLocalMedia>) -> Unit)? = null) {
        activity?.let {
            if (it is KBaseActivity) {
                it.pictrueSelectorForLocalMedia(selectionMedia = selectionMedia, type = type, maxSelectNum = maxSelectNum, imageSpanCount = imageSpanCount, isCompress = isCompress, isCamera = isCamera, selectCallback = selectCallback)
            }
        }
    }

    //fixme pictrueSelectorForPath(type = PictureConfig.TYPE_VIDEO) 这个是视频选择器
    open fun pictrueSelectorForPath(selectionMedia: MutableList<KLocalMedia>? = KPictureSelector.selectionMedia, type: Int = PictureConfig.TYPE_IMAGE, maxSelectNum: Int = 1, imageSpanCount: Int = KPictureSelector.imageSpanCount, isCompress: Boolean = true, isCamera: Boolean = true, selectCallback: ((path: ArrayList<String>) -> Unit)? = null) {
        activity?.let {
            if (it is KBaseActivity) {
                it.pictrueSelectorForPath(selectionMedia = selectionMedia, type = type, maxSelectNum = maxSelectNum, imageSpanCount = imageSpanCount, isCompress = isCompress, isCamera = isCamera, selectCallback = selectCallback)
            }
        }
    }

    //回调文件
    open fun pictrueSelectorForFile(selectionMedia: MutableList<KLocalMedia>? = KPictureSelector.selectionMedia, type: Int = PictureConfig.TYPE_IMAGE, maxSelectNum: Int = 1, imageSpanCount: Int = KPictureSelector.imageSpanCount, isCompress: Boolean = true, isCamera: Boolean = true, selectCallback: ((path: ArrayList<File>) -> Unit)? = null) {
        activity?.let {
            if (it is KBaseActivity) {
                it.pictrueSelectorForFile(selectionMedia = selectionMedia, type = type, maxSelectNum = maxSelectNum, imageSpanCount = imageSpanCount, isCompress = isCompress, isCamera = isCamera, selectCallback = selectCallback)
            }
        }
    }

    /**
     * 图片预览
     * @param position 当前预览图片下标
     * @param medias 预览图片集合
     */
    open fun pictruePreview(position: Int = 0, medias: MutableList<KLocalMedia>? = KPictureSelector.selectionMedia) {
        activity?.let {
            if (it is KBaseActivity) {
                it.pictruePreview(position = position, medias = medias)
            }
        }
    }

    /**
     * 图片预览
     * @param files 图片文件集合
     * @param position 当前预览图片下标。
     */
    open fun pictruePreviewForFile(files: MutableList<File>?, position: Int = 0) {
        activity?.let {
            if (it is KBaseActivity) {
                it.pictruePreviewForFile(files = files, position = position)
            }
        }
    }

    open fun pictruePreviewForFile(file: File?, position: Int = 0) {
        activity?.let {
            if (it is KBaseActivity) {
                it.pictruePreviewForFile(file = file, position = position)
            }
        }
    }

    open fun pictruePreviewForPath(paths: MutableList<String>?, position: Int = 0) {
        activity?.let {
            if (it is KBaseActivity) {
                it.pictruePreviewForPath(paths = paths, position = position)
            }
        }
    }

    open fun pictruePreviewForPath(path: String?, position: Int = 0) {
        activity?.let {
            if (it is KBaseActivity) {
                it.pictruePreviewForPath(path = path, position = position)
            }
        }
    }

    /**
     * 图片裁剪
     * @param file 裁剪文件
     * @param w 裁剪宽度比例
     * @param h 高度比例
     * @param isDel 裁剪之后，是否删除裁剪原文件。true删除，false不删除。默认不删除。
     * @param callback2 回调，返回裁剪结果文件。
     */
    open fun crop(file: File, w: Int = 1, h: Int = 1, isDel: Boolean = false, callback2: (file: File) -> Unit) {
        KPictureUtils.crop(file = file, w = w, h = h, isDel = isDel, callback2 = callback2)
    }

    open fun crop(path: String, w: Int = 1, h: Int = 1, isDel: Boolean = false, callback2: (file: File) -> Unit) {
        var file = File(path)
        KPictureUtils.crop(file = file, w = w, h = h, isDel = isDel, callback2 = callback2)
    }

    override fun onDestroyView() {
        try {
            super.onDestroyView()
        } catch (e: Exception) {
            KLoggerUtils.e("Fragment onDestroyView()销毁异常：\t" + KCatchException.getExceptionMsg(e), true)
        }
    }

    override fun onDestroy() {
        try {
            super.onDestroy()
            //fixme Fragment销毁。
            mFragments?.forEach {
                it?.onDestroy()//fixme 可以重复销毁调用onDestroy（）不会异常。亲测。
            }
            mFragments?.clear()
            mFragments = null
            mShowFragments?.clear()
            mShowFragments = null
            mCurrentFragment = null
            act = null
        } catch (e: Exception) {
            KLoggerUtils.e("Fragment onDestroy()销毁异常：\t" + KCatchException.getExceptionMsg(e), true)
        }
    }

    companion object {
        //获取位图
        open fun getBitmapFromAssets(filePath: String, isRGB_565: Boolean = false): Bitmap {
            return KAssetsUtils.getInstance().getBitmapFromAssets(filePath, isRGB_565)
        }

        open fun getBitmapFromResource(resID: Int, isRGB_565: Boolean = false): Bitmap {
            return KAssetsUtils.getInstance().getBitmapFromResource(resID, isRGB_565)
        }

        open fun getBitmapFromFile(filePath: String, isRGB_565: Boolean = false): Bitmap {
            return KAssetsUtils.getInstance().getBitmapFromFile(filePath, isRGB_565)
        }
    }

}